#include "Trie.hh"

#include <iostream>

Trie::Trie()
{
  Trie('\0', 0);
}

Trie::Trie(char value,
     unsigned frequency)
{
  this->value = value;
  this->frequency = frequency;
}

Trie::~Trie()
{
  std::list<Trie*>::iterator it = sons.begin();

  while ( it != sons.end() )
    {
      delete *it;
      ++it;
    }
}

void Trie::add_word(const char* word,
	      unsigned frequency)
{
  std::list<Trie*>::iterator it = sons.begin();

  while ( (it != sons.end()) && ((*it)->value < word[0]) )
    {
      ++it;
    }

  if ( (it == sons.end()) || ((*it)->value != word[0]) )
    {
      it = sons.insert(it, new Trie(word[0], 0));
    }

  if (word[1] != '\0')
    {
      (*it)->add_word(word + 1, frequency);
    }
  else
    {
      (*it)->frequency = frequency;
    }
}

void Trie::print (unsigned offset) const
{
  for (unsigned i = 0; i < offset; ++i)
    std::cout << " ";
  std::cout << value;
  std::cout << " " << sons.size () << " " << frequency;
  std::cout << std::endl;
  for (std::list<Trie*>::const_iterator it = sons.begin(); it != sons.end (); ++it)
    (*it)->print (offset + 1);
}

char Trie::get_value() const
{
  return value;
}

unsigned Trie::size() const
{
  unsigned result = sons.size() + 1;

  for (std::list<Trie*>::const_iterator it = sons.begin();
       it != sons.end(); ++it)
    {
      result += (*it)->size();
    }

  return result;
}

unsigned Trie::get_frequency() const
{
  return frequency;
}

unsigned Trie::get_nb_sons() const
{
  return sons.size();
}

const std::list<Trie*>* Trie::get_sons() const
{
  return &sons;
}
